package top.broncho.gank.ui.fragment

import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.chad.library.adapter.base.BaseQuickAdapter
import top.broncho.gank.R
import top.broncho.gank.adapter.HomeAdapter
import top.broncho.gank.app.App
import top.broncho.gank.bean.Article
import top.broncho.gank.bean.ArticleResponseBody
import top.broncho.gank.constant.Constant
import top.broncho.gank.databinding.FragmentSquareBinding
import top.broncho.gank.ext.showSnackMsg
import top.broncho.gank.ext.showToast
import top.broncho.gank.ui.activity.CommonActivity
import top.broncho.gank.ui.activity.ContentActivity
import top.broncho.gank.ui.activity.LoginActivity
import top.broncho.gank.utils.NetWorkUtil
import top.broncho.gank.widget.SpaceItemDecoration
import kotlinx.android.synthetic.main.fragment_refresh_layout.*
import top.broncho.mvvm.base.BaseDiFragment

/**
 * @author chenxz
 * @date 2019/11/16
 * @desc 广场
 */
class SquareFragment : BaseDiFragment<FragmentSquareBinding>() {

    companion object {
        fun getInstance(): SquareFragment = SquareFragment()
    }

    private val viewModel by viewModels<SquareViewModel> { viewModelFactory }
    private val datas = mutableListOf<Article>()

    /**
     * 每页数据的个数
     */
    protected var pageSize = 20

    /**
     * 是否是下拉刷新
     */
    protected var isRefresh = true

    /**
     * LinearLayoutManager
     */
    protected val linearLayoutManager: LinearLayoutManager by lazy {
        LinearLayoutManager(activity)
    }

    /**
     * RecyclerView Divider
     */
    private val recyclerViewItemDecoration by lazy {
        activity?.let {
            SpaceItemDecoration(it)
        }
    }

    /**
     * RefreshListener
     */
    protected val onRefreshListener = SwipeRefreshLayout.OnRefreshListener {
        isRefresh = true
        onRefreshList()
    }

    /**
     * LoadMoreListener
     */
    protected val onRequestLoadMoreListener = BaseQuickAdapter.RequestLoadMoreListener {
        isRefresh = false
        swipeRefreshLayout.isRefreshing = false
        onLoadMoreList()
    }

    private val mAdapter: HomeAdapter by lazy {
        HomeAdapter(activity, datas)
    }


    override fun getLayoutId(): Int = R.layout.fragment_square


    fun hideLoading() {
        if (isRefresh) {
            mAdapter.setEnableLoadMore(true)
        }
        swipeRefreshLayout?.isRefreshing = false
    }

    fun showError(errorMsg: String) {
        mLayoutStatusView?.showError()
        if (isRefresh) {
            mAdapter.setEnableLoadMore(true)
        } else {
            mAdapter.loadMoreFail()
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView(view)
        viewModel.article.observe({ lifecycle }) {
            hideLoading()
            if (it.isFailure) {
                showError(it.exceptionOrNull().toString())
                return@observe
            }
            showSquareList(it.getOrThrow())
        }

        viewModel.collect.observe({ lifecycle }) {
            showCollectSuccess(it.isSuccess)
        }
        viewModel.cancel.observe({ lifecycle }) {
            showCancelCollectSuccess(it.isSuccess)
        }
    }

    fun initView(view: View) {
        setHasOptionsMenu(true)
        mLayoutStatusView = multiple_status_view
        swipeRefreshLayout.run {
            setOnRefreshListener(onRefreshListener)
        }
        recyclerView.run {
            layoutManager = linearLayoutManager
            itemAnimator = DefaultItemAnimator()
            recyclerViewItemDecoration?.let { addItemDecoration(it) }
        }
        recyclerView.adapter = mAdapter

        mAdapter.run {
            bindToRecyclerView(recyclerView)
            setOnLoadMoreListener(onRequestLoadMoreListener, recyclerView)
            onItemClickListener = this@SquareFragment.onItemClickListener
            onItemChildClickListener = this@SquareFragment.onItemChildClickListener
        }
    }

    override fun onResume() {
        super.onResume()
        if (viewModel.article.value == null) {
            lazyLoad()
        }
    }

    fun lazyLoad() {
        mLayoutStatusView?.showLoading()
        viewModel.getSquareList(0)
    }

    fun onRefreshList() {
        mAdapter.setEnableLoadMore(false)
        viewModel.getSquareList(0)
    }

    fun onLoadMoreList() {
        val page = mAdapter.data.size / pageSize
        viewModel.getSquareList(page)
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.menu_square, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_add -> {
                Intent(activity, CommonActivity::class.java).run {
                    putExtra(Constant.TYPE_KEY, Constant.Type.SHARE_ARTICLE_TYPE_KEY)
                    startActivity(this)
                }
            }
        }
        return super.onOptionsItemSelected(item)
    }

    fun scrollToTop() {
        recyclerView.run {
            if (linearLayoutManager.findFirstVisibleItemPosition() > 20) {
                scrollToPosition(0)
            } else {
                smoothScrollToPosition(0)
            }
        }
    }

    fun showSquareList(body: ArticleResponseBody) {
        body.datas.let {
            mAdapter.run {
                if (isRefresh) {
                    replaceData(it)
                } else {
                    addData(it)
                }
                pageSize = body.size
                if (body.over) {
                    loadMoreEnd(isRefresh)
                } else {
                    loadMoreComplete()
                }
            }
        }
        if (mAdapter.data.isEmpty()) {
            mLayoutStatusView?.showEmpty()
        } else {
            mLayoutStatusView?.showContent()
        }
    }

    fun showCollectSuccess(success: Boolean) {
        if (success) {
            showToast(resources.getString(R.string.collect_success))
        }
    }

    fun showCancelCollectSuccess(success: Boolean) {
        if (success) {
            showToast(resources.getString(R.string.cancel_collect_success))
        }
    }

    /**
     * ItemClickListener
     */
    private val onItemClickListener = BaseQuickAdapter.OnItemClickListener { _, _, position ->
        if (datas.size != 0) {
            val data = datas[position]
            ContentActivity.start(activity, data.id, data.title, data.link)
        }
    }

    /**
     * ItemChildClickListener
     */
    private val onItemChildClickListener =
        BaseQuickAdapter.OnItemChildClickListener { _, view, position ->
            if (datas.size != 0) {
                val data = datas[position]
                when (view.id) {
                    R.id.iv_like -> {
                        if (isLogin) {
                            if (!NetWorkUtil.isNetworkAvailable(App.context)) {
                                showSnackMsg(resources.getString(R.string.no_network))
                                return@OnItemChildClickListener
                            }
                            val collect = data.collect
                            data.collect = !collect
                            mAdapter.setData(position, data)
                            if (collect) {
                                viewModel.cancelCollectArticle(data.id)
                            } else {
                                viewModel.addCollectArticle(data.id)
                            }
                        } else {
                            Intent(activity, LoginActivity::class.java).run {
                                startActivity(this)
                            }
                            showToast(resources.getString(R.string.login_tint))
                        }
                    }
                }
            }
        }

}